diff --git a/src/Makefile b/src/Makefile
index 30d64be2..ae7ec875 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -27,7 +27,7 @@ NODOTABIVER= 51
 DEFAULT_CC = gcc
 #
 # LuaJIT builds as a native 32 or 64 bit binary by default.
-CC= $(DEFAULT_CC)
+CC ?= $(DEFAULT_CC)
 #
 # Use this if you want to force a 32 bit build on a 64 bit multilib OS.
 #CC= $(DEFAULT_CC) -m32
@@ -71,10 +71,10 @@ CCWARN= -Wall
 # as dynamic mode.
 #
 # Mixed mode creates a static + dynamic library and a statically linked luajit.
-BUILDMODE= mixed
+#BUILDMODE= mixed
 #
 # Static mode creates a static library and a statically linked luajit.
-#BUILDMODE= static
+BUILDMODE= static
 #
 # Dynamic mode creates a dynamic library and a dynamically linked luajit.
 # Note: this executable will only run when the library is installed!
@@ -99,7 +99,7 @@ XCFLAGS=
 # enabled by default. Some other features that *might* break some existing
 # code (e.g. __pairs or os.execute() return values) can be enabled here.
 # Note: this does not provide full compatibility with Lua 5.2 at this time.
-#XCFLAGS+= -DLUAJIT_ENABLE_LUA52COMPAT
+XCFLAGS+= -DLUAJIT_ENABLE_LUA52COMPAT
 #
 # Disable the JIT compiler, i.e. turn LuaJIT into a pure interpreter.
 #XCFLAGS+= -DLUAJIT_DISABLE_JIT
@@ -212,7 +212,7 @@ TARGET_STCC= $(STATIC_CC)
 TARGET_DYNCC= $(DYNAMIC_CC)
 TARGET_LD= $(CROSS)$(CC)
 TARGET_AR= $(CROSS)ar rcus
-TARGET_STRIP= $(CROSS)strip
+TARGET_STRIP?= $(CROSS)strip

 TARGET_LIBPATH= $(or $(PREFIX),/usr/local)/$(or $(MULTILIB),lib)
 TARGET_SONAME= libluajit-$(ABIVER).so.$(MAJVER)
@@ -598,7 +598,7 @@ endif

 Q= @
 E= @echo
-#Q=
+Q=
 #E= @:

 ##############################################################################
diff --git a/build.py b/build.py
new file mode 100755
index 00000000..1201542c
--- /dev/null
+++ b/build.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+import shutil
+
+def main():
+    parser = argparse.ArgumentParser()
+    parser.add_argument("--prefix")
+    args = parser.parse_args()
+    src_dir = os.path.dirname(os.path.realpath(__file__))
+    shutil.copytree(src_dir, os.path.basename(src_dir))
+    os.chdir(os.path.basename(src_dir))
+
+    os.environ["MACOSX_DEPLOYMENT_TARGET"] = "10.8"
+    os.environ["DEFAULT_CC"] = os.environ.get("CC", "")
+    os.environ["TARGET_CFLAGS"] = os.environ.get("CFLAGS", "") + " -fno-function-sections -fno-data-sections"
+    os.environ["TARGET_LDFLAGS"] = os.environ.get("CFLAGS", "") + " -fno-function-sections -fno-data-sections"
+    os.environ["CFLAGS"] = ""
+    os.environ["LDFLAGS"] = ""
+
+    # Don't strip the binary - it doesn't work when cross-compiling, and we don't use it anyway.
+    os.environ["TARGET_STRIP"] = "@echo"
+    os.environ["MAKE"] = "/usr/bin/make"
+
+    # Remove LuaJIT from ASAN for now.
+    # TODO(htuch): Remove this when https://github.com/envoyproxy/envoy/issues/6084 is resolved.
+    if "ENVOY_CONFIG_ASAN" in os.environ or "ENVOY_CONFIG_MSAN" in os.environ:
+      os.environ["TARGET_CFLAGS"] += " -fsanitize-blacklist=%s/com_github_luajit_luajit/clang-asan-blocklist.txt" % os.environ["PWD"]
+      with open("clang-asan-blocklist.txt", "w") as f:
+        f.write("fun:*\n")
+
+    os.system('"{}" -j{} V=1 PREFIX="{}" install'.format(os.environ["MAKE"], os.cpu_count(), args.prefix))
+
+def win_main():
+    src_dir = os.path.dirname(os.path.realpath(__file__))
+    dst_dir = os.getcwd() + "/luajit"
+    shutil.copytree(src_dir, os.path.basename(src_dir))
+    os.chdir(os.path.basename(src_dir) + "/src")
+    os.system('msvcbuild.bat ' + os.getenv('WINDOWS_DBG_BUILD', '') + ' static')
+    os.makedirs(dst_dir + "/lib", exist_ok=True)
+    shutil.copy("lua51.lib", dst_dir + "/lib")
+    os.makedirs(dst_dir + "/include/luajit-2.1", exist_ok=True)
+    for header in ["lauxlib.h", "luaconf.h", "lua.h", "lua.hpp", "luajit.h", "lualib.h"]:
+      shutil.copy(header, dst_dir + "/include/luajit-2.1")
+    os.makedirs(dst_dir + "/bin", exist_ok=True)
+    shutil.copy("luajit.exe", dst_dir + "/bin")
+
+if os.name == 'nt':
+  win_main()
+else:
+  main()
+
